﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Top.Data;

namespace Top.PointStore.Business
{
    /*功能说明:积分商品操作管理类
    *版本:
    *参与人:王士锋
    *修改日期:2015.3.4
    */
    /// <summary>积分商品
    /// </summary>
    public static class PointProductManager
    {

        /// <summary>
        /// 判断商品是否存在
        /// </summary>
        /// <param name="productKid"></param>
        /// <returns></returns>
        public static async Task<int> IsExists(int productKid)
        {
            using (var db = new DbTour())
            {
                const string sql = "select count(1) from T_PointProduct where Kid={0}";
                return await db.Sql(sql, productKid).ExecuteScalar<int>();
            }
        }

        /// <summary>增加一条数据
        /// <para>0:新增失败</para>
        /// <para>新增成功返回大于0</para>
        /// <para>-1:商品分类编号不能为空</para>
        /// <para>-2:商品名称不能为空</para>
        /// <para>-3:积分不能为空</para>
        /// <para>-4:商品库存不能为空</para>
        /// <para>-5:是否开启规则不能为空</para>
        /// <para>-6:处理类型不能为空</para>
        /// <para>-7:自动处理时来源不能为空</para>
        /// <para>-8:兑换类型不能为空</para>
        /// <para>-9:用户兑换次数不能为空</para>
        /// <para>-10:商品编码不能含有特殊字符</para>
        /// <para>-11:每日兑换数量不能为空</para>
        /// <para>-12:每日兑换开始日期不能为空</para>
        /// <para>-13:每日兑换结束日期不能为空</para>
        /// </summary>
        public static async Task<int> Add(PointProductExpand model)
        {
            #region 参数验证
            if (model.F_CategoryKid <= 0)
            {
                return -1;
            }
            if (string.IsNullOrEmpty(model.F_ProductName))
            {
                return -2;
            }
            if (model.F_PointNum < 0)
            {
                return -3;
            }
            if (model.F_InventoryNum < 0)
            {
                return -4;
            }
            if (model.F_IsExchange < 0)
            {
                return -5;
            }
            if (model.F_Status < 0)
            {
                return -6;
            }
            if (model.F_Status == 0)
            {
                if (model.F_Source == "")
                {
                    return -7;
                }
            }

            if (model.F_ExchangeType < 0)
            {
                return -8;
            }
            if (model.F_UserExchangeNum < 0)
            {
                return -9;
            }
            if (model.F_Code.Contains("|"))
            {
                return -10;
            }
            if (model.F_IsExchange == 1)
            {
                if (model.F_ExchangeNum <= 0)
                {
                    return -11;
                }
                if (string.IsNullOrEmpty(model.F_ExchangeBeginTime))
                {
                    return -12;
                }
                if (string.IsNullOrEmpty(model.F_ExchangeEndTime))
                {
                    return -13;
                }
            }
            #endregion
            //积分商品插入一条记录
            const string sql = @"insert into T_PointProduct (F_ProductName,F_PicUrl,F_Description,F_CategoryKid,F_CreatedTime,F_UpdatedTime,F_IsDelete,F_Code) 
                values ({0:F_ProductName},
                        {0:F_PicUrl},
                        {0:F_Description},
                        {0:F_CategoryKid},
                        {0:F_CreatedTime},
                        {0:F_UpdatedTime},
                        {0:F_IsDelete},
                        {0:F_Code});
                select LAST_INSERT_ID()";

            using (var db = new DbTour())
            {
                await db.Begin();
                int id = await db.Sql(sql, model).ExecuteScalar<int>();
                if (id > 0)
                {
                    //库存插入一条记录
                    const string sql2 = "insert into T_ProductInventory(F_ProductKid,F_InventoryNum,F_Source,F_StockNum,F_ProductPrice) values ({0:F_ProductKid},{0:F_InventoryNum},{0:F_Source},{0:F_StockNum},{0:F_ProductPrice});select LAST_INSERT_ID() ";
                    var productInventoryKid = await db.Sql(sql2, new { F_ProductKid = id, F_InventoryNum = model.F_InventoryNum, F_Source = model.F_Source, F_StockNum = model.F_StockNum, F_ProductPrice = model.F_ProductPrice }).ExecuteScalar<int>();
                    if (productInventoryKid <= 0)//库存插入失败，回滚
                    {
                        db.Rollback();
                        return 0;
                    }

                    //产品图片插入
                    if (!string.IsNullOrEmpty(model.ProductPic))
                    {
                        var picList = model.ProductPic.Split('|');
                        for (int i = 0; i < picList.Length; i++)
                        {
                            if (!string.IsNullOrEmpty(picList[i]))
                                await ProductPicManager.Add(new T_ProductPic { F_ProductKid = id, F_PicUrl = picList[i] });
                        }

                    }

                    //积分规则插入一条记录
                    int ruleId = await ExchangeRuleManager.Add(new T_ExchangeRuleExpand()
                     {
                         F_ProductKid = id,
                         F_BeginTime = model.F_BeginTime,
                         F_EndTime = model.F_EndTime,
                         F_PointNum = model.F_PointNum,
                         F_Disabled = model.F_Disabled,
                         F_IsExchange = model.F_IsExchange,
                         F_Status = model.F_Status,
                         F_ExchangeType = model.F_ExchangeType,
                         F_UserExchangeNum = model.F_UserExchangeNum,
                         F_ExchangeNum = model.F_ExchangeNum,
                         F_ExchangeBeginTime = model.F_ExchangeBeginTime,
                         F_ExchangeEndTime = model.F_ExchangeEndTime,
                         F_IsDelete = 0,
                         RuleToCity = model.RuleToCity,
                         F_IsMeskill = model.F_IsMeskill
                     });



                    if (ruleId <= 0)//积分规则插入失败，回滚
                    {
                        db.Rollback();
                        return 0;
                    }

                    var productShowKid = await ProductShowManager.Add(new T_ProductShow()
                     {
                         F_ProductKid = id,
                         F_ExchangeRuleKid = ruleId,
                         F_ShowName = model.F_ProductName,
                         F_Sort = model.F_Sort,
                         F_AddedTime = model.F_BeginTime,//DateTime.Now,
                         F_SoldoutTime = model.F_EndTime,//DateTime.Now.AddMonths(1),
                         F_Status = model.TypeId,
                         F_CreatedTime = DateTime.Now,
                         F_UpdatedTime = DateTime.Now,
                         F_IsDelete = 0
                     });
                    if (productShowKid <= 0)//商品展示数据插入失败，回滚
                    {
                        db.Rollback();
                        return 0;
                    }
                }
                db.Commit();
                if (model.TypeId==1)
                {
                    await MemoryTable.Init_ProductShow_table();
                }                
                return id;
            }
        }


        public static async Task<int> UpdateField(int productKid, DbTour db)
        {
            if (productKid <= 0) return -1;
            const string sql = @"update T_ProductInventory set F_InventoryNum=F_InventoryNum-1 where F_InventoryNum>=1 and F_ProductKid={0}";
            return await db.Sql(sql, productKid).ExecuteNonQuery();
        }
        /// <summary>更新积分商品，展示商品，兑换规则
        /// <para>0:更新失败</para>
        /// <para>-1:商品id有误</para>
        /// <para>-2:商品名称不能为空</para>
        /// <para>-3:详细说明不能为空</para>
        /// <para>-4:积分需为正数</para>
        /// <para>-5:自动处理时来源不能为空</para>
        /// <para>更新成功返回大于0</para>
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static async Task<int> UpdateField(PointProductExpand model)
        {
            if (model.Kid <= 0) return -1;
            if (string.IsNullOrEmpty(model.F_ProductName))
            {
                return -2;
            }
            if (string.IsNullOrEmpty(model.F_Description))
            {
                return -3;
            }
            if (model.F_PointNum < 0)
            {
                return -4;
            }
            if (model.F_Status == 0)
            {
                if (string.IsNullOrEmpty(model.F_Source))
                {
                    return -5;
                }
            }

            using (var db = new DbTour())
            {
                await db.Begin();
                //更新积分产品
                const string sql = "update T_PointProduct set F_ProductName={0:F_ProductName},F_Description={0:F_Description},F_PicUrl={0:F_PicUrl},F_CategoryKid={0:F_CategoryKid},F_UpdatedTime=now() where Kid={0:Kid}";
                var count = await db.Sql(sql, new { F_ProductName = model.F_ProductName, F_Description = model.F_Description, F_PicUrl = model.F_PicUrl, Kid = model.Kid, F_CategoryKid = model.F_CategoryKid }).ExecuteNonQuery();
                if (count == 0) return 0;

                //更新产品展示
                const string sql2 = "update T_ProductShow set F_ShowName={0:F_ShowName},F_Sort={0:F_Sort} where F_ProductKid={0:F_ProductKid}";
                count = await db.Sql(sql2, new { F_ShowName = model.F_ProductName, F_ProductKid = model.Kid, F_Sort = model.F_Sort }).ExecuteNonQuery();
                if (count == 0)
                {
                    db.Rollback();
                    return 0;
                }
                //更新兑换规则
                const string sql3 = "update T_ExchangeRule set F_PointNum={0:F_PointNum},F_Status={0:F_Status} where F_ProductKid={0:F_ProductKid}";
                count = await db.Sql(sql3, new { F_PointNum = model.F_PointNum, F_Status = model.F_Status, F_ProductKid = model.Kid }).ExecuteNonQuery();
                if (count == 0)
                {
                    db.Rollback();
                    return 0;
                }
                //更新库存
                const string sql5 = "update T_ProductInventory set F_InventoryNum={0} where F_ProductKid={1}";
                count = await db.Sql(sql5, model.F_InventoryNum, model.Kid).ExecuteNonQuery();
                if (count == 0)
                {
                    db.Rollback();
                    return 0;
                }
                //上架数量
                const string sql6 = "update T_ProductInventory set F_StockNum={0} where F_ProductKid={1}";
                count = await db.Sql(sql6, model.F_StockNum, model.Kid).ExecuteNonQuery();
                if (count == 0)
                {
                    db.Rollback();
                    return 0;
                }
                //商品单价
                const string sql7 = "update T_ProductInventory set F_ProductPrice={0} where F_ProductKid={1}";
                count = await db.Sql(sql7, model.F_ProductPrice, model.Kid).ExecuteNonQuery();
                if (count == 0)
                {
                    db.Rollback();
                    return 0;
                }
                if (model.F_Status == 0) //自动处理的时候修改来源
                {
                    const string sql4 =
                        "update T_ProductInventory set F_Source={0:F_Source} where F_ProductKid={0:F_ProductKid}";
                    count = await db.Sql(sql4, new { F_Source = model.F_Source, F_ProductKid = model.Kid }).ExecuteNonQuery();
                    if (count == 0)
                    {
                        db.Rollback();
                        return 0;
                    }
                }
                db.Commit();
                await MemoryTable.Init_ProductShow_table();
                return 1;
            }
        }

        /// <summary>PointProductExpand模型参数验证
        /// <para>0:验证成功</para>
        /// <para>-1:商品id有误</para>
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private static int CheckingPointProductExpand(PointProductExpand model)
        {
            if (model.Kid < 0) return -1;
            return 0;
        }
        /// <summary>更新
        /// <para>0:新增失败</para>
        /// <para>新增成功返回大于0</para>
        /// <para>-1:商品分类编号不能为空</para>
        /// <para>-2:商品名称不能为空</para>
        /// <para>-3:积分不能为空</para>
        /// <para>-4:商品库存不能为空</para>
        /// <para>-5:是否开启规则不能为空</para>
        /// <para>-6:处理类型不能为空</para>
        /// <para>-7:自动处理时来源不能为空</para>
        /// <para>-8:兑换类型不能为空</para>
        /// <para>-9:用户兑换次数不能为空</para>
        /// <para>-10:商品编码不能含有特殊字符</para>
        /// <para>-11:每日兑换数量不能为空</para>
        /// <para>-12:每日兑换开始日期不能为空</para>
        /// <para>-13:每日兑换结束日期不能为空</para>
        /// <para>-14:商品id有误</para>
        /// </summary>
        public static async Task<int> Update(PointProductExpand model)
        {
            #region 参数验证
            if (model.F_CategoryKid <= 0)
            {
                return -1;
            }
            if (string.IsNullOrEmpty(model.F_ProductName))
            {
                return -2;
            }
            if (model.F_PointNum < 0)
            {
                return -3;
            }
            if (model.F_InventoryNum < 0)
            {
                return -4;
            }
            if (model.F_IsExchange < 0)
            {
                return -5;
            }
            if (model.F_Status < 0)
            {
                return -6;
            }
            if (model.F_Status == 0)
            {
                if (model.F_Source == "")
                {
                    return -7;
                }
            }

            if (model.F_ExchangeType < 0)
            {
                return -8;

            }
            if (model.F_UserExchangeNum < 0)
            {
                return -9;

            }
            if (model.F_Code.Contains("|"))
            {
                return -10;
            }
            if (model.F_IsExchange == 1)
            {
                if (model.F_ExchangeNum <= 0)
                {
                    return -11;

                }
                if (string.IsNullOrEmpty(model.F_ExchangeBeginTime))
                {
                    return -12;
                }
                if (string.IsNullOrEmpty(model.F_ExchangeBeginTime))
                {
                    return -13;
                }
            }

            if (model.Kid <= 0)
            {
                return -14;
            }
            #endregion
            const string sql = @"update T_PointProduct set 
                F_ProductName={0:F_ProductName},
                F_PicUrl={0:F_PicUrl},
                F_Description={0:F_Description},
                F_CategoryKid={0:F_CategoryKid},
                F_UpdatedTime={0:F_UpdatedTime},
                F_Code={0:F_Code}
              where Kid={0:Kid}";

            using (var db = new DbTour())
            {
                int id = await db.Sql(sql, model).ExecuteNonQuery();
                if (id > 0)
                {
                    //更新库存
                    const string sql2 = "update T_ProductInventory set F_InventoryNum={0:F_InventoryNum},F_Source={0:F_Source},F_StockNum={0:F_StockNum},F_ProductPrice={0:F_ProductPrice} where F_ProductKid={0:F_ProductKid}";
                    await db.Sql(sql2, new { F_ProductKid = model.Kid, F_InventoryNum = model.F_InventoryNum, F_Source = model.F_Source, F_StockNum = model.F_StockNum, F_ProductPrice = model.F_ProductPrice }).ExecuteNonQuery();


                    //产品图片插入
                    if (!string.IsNullOrEmpty(model.ProductPic))
                    {
                        const string sql3 = @"
                        update t_productpic
                        set f_picurl = {0}
                        where F_ProductKid = {1}
                        ";
                        await db.Sql(sql3, model.ProductPic,model.Kid).ExecuteScalar();
                    }

                    int ruleId = 0;

                    if (model.ruleKid > 0)
                    {
                        //更新积分规则
                        await ExchangeRuleManager.Update(new T_ExchangeRuleExpand()
                         {
                             F_ProductKid = model.Kid,
                             F_BeginTime = model.F_BeginTime,
                             F_EndTime = model.F_EndTime,
                             F_PointNum = model.F_PointNum,
                             F_Disabled = model.F_Disabled,
                             F_Status = model.F_Status,
                             F_ExchangeType = model.F_ExchangeType,
                             F_UserExchangeNum = model.F_UserExchangeNum,
                             F_ExchangeNum = model.F_ExchangeNum,
                             F_ExchangeBeginTime = model.F_ExchangeBeginTime,
                             F_ExchangeEndTime = model.F_ExchangeEndTime,
                             F_UpdatedTime = DateTime.Now,
                             F_IsMeskill = model.F_IsMeskill,
                             F_IsExchange = model.F_IsExchange,
                             Kid = model.ruleKid

                         });
                        ruleId = model.ruleKid;
                    }
                    else
                    {
                        //积分规则插入一条记录
                        ruleId = await ExchangeRuleManager.Add(new T_ExchangeRuleExpand()
                        {
                            F_ProductKid = model.Kid,
                            F_BeginTime = model.F_BeginTime,
                            F_EndTime = model.F_EndTime,
                            F_PointNum = model.F_PointNum,
                            F_Disabled = model.F_Disabled,
                            F_IsExchange = model.F_IsExchange,
                            F_Status = model.F_Status,
                            F_ExchangeType = model.F_ExchangeType,
                            F_UserExchangeNum = model.F_UserExchangeNum,
                            F_ExchangeNum = model.F_ExchangeNum,
                            F_ExchangeBeginTime = model.F_ExchangeBeginTime,
                            F_ExchangeEndTime = model.F_ExchangeEndTime,
                            F_IsDelete = 0,
                            RuleToCity = model.RuleToCity,
                            F_IsMeskill = model.F_IsMeskill
                        });

                    }

                    await db.Sql("delete from T_RuleToCity where F_RuleKid = {0}", ruleId).ExecuteNonQuery();
                    //插入规则与城市
                    if (!string.IsNullOrEmpty(model.RuleToCity))
                    {
                        var cityList = model.RuleToCity.Split('|');
                        for (int i = 0; i < cityList.Length; i++)
                        {
                            const string sql4 = "insert into T_RuleToCity([F_RuleKid],[F_CityKid]) values ({0},{1})";
                            await db.Sql(sql4, ruleId, cityList[i]).ExecuteScalar();
                            //TODO
                        }

                    }

                    var productShowKid = await ProductShowManager.UpdateByProductKid(new T_ProductShow()
                    {
                        F_ProductKid = model.Kid,
                        F_ExchangeRuleKid = ruleId,
                        F_ShowName = model.F_ProductName,
                        F_Sort = model.F_Sort,
                        F_AddedTime = model.F_BeginTime,//DateTime.Now,
                        F_SoldoutTime = model.F_EndTime,//DateTime.Now.AddMonths(1),
                        F_Status = model.TypeId,
                        F_CreatedTime = DateTime.Now,
                        F_UpdatedTime = DateTime.Now,
                        F_IsDelete = 0
                    });
                    if (productShowKid <= 0)//商品展示数据插入失败，回滚
                    {
                        db.Rollback();
                        return 0;
                    }
                }
                if (model.TypeId==1)
                {
                    await MemoryTable.Init_ProductShow_table(); 
                }               
                return id;
            }
        }


        /// <summary>根据kid获取积分商品
        /// </summary>
        /// <param name="kid">商品kid</param>
        /// <returns></returns>
        public static async Task<PointProductExpand> Get(int kid)
        {
            if (kid < 0) return null;
            using (var db = new DbTour())
            {
                //积分商品
                const string sql = @"
                        SELECT 
	                        p.*
	                        ,s.F_Sort
                        FROM T_PointProduct AS p
                        LEFT JOIN T_ProductShow AS s ON p.Kid = s.F_ProductKid 
                        WHERE p.Kid = {0} limit 1";
                var result = await db.Sql(sql, kid).FirstOrDefault<PointProductExpand>();
                //result.F_EndTime = result.F_EndTime.AddDays(-1);
                //库存
                const string sql2 = @"select * from T_ProductInventory where F_ProductKid = {0} limit 1";
                var ProductInventory = await db.Sql(sql2, kid).FirstOrDefault<T_ProductInventory>();
                result.F_InventoryNum = ProductInventory.F_InventoryNum;
                result.F_Source = ProductInventory.F_Source;
                result.F_StockNum = ProductInventory.F_StockNum;
                result.F_ProductPrice = ProductInventory.F_ProductPrice;
                //产品图片
                result.T_ProductPic = await ProductPicManager.GetList(kid);

                //产品规则
                result.T_ExchangeRule = await ExchangeRuleManager.GetModelByProductKid(kid);
                result.T_ExchangeRule.F_EndTime = result.T_ExchangeRule.F_EndTime.AddDays(-1);
                return result;
            }

        }

        /// <summary>更新库存
        /// </summary>
        public static async Task<int> UpdateField(int productKid, int inventoryNum)
        {
            if (productKid <= 0) return -1;
            const string sql = @"update T_ProductInventory set F_InventoryNum={0:F_InventoryNum} where F_ProductKid={0:F_ProductKid}";
            using (var db = new DbTour())
            {
                var obj = new
                {
                    F_InventoryNum = inventoryNum,
                    F_ProductKid = productKid
                };
                return await db.Sql(sql, obj).ExecuteNonQuery();
            }
        }

        public static async Task<int> UpdateField(int productKid)
        {
            if (productKid <= 0) return -1;
            using (var db = new DbTour())
            {
                //                const string sql = @"update T_ProductInventory set F_InventoryNum=F_InventoryNum-1 where F_InventoryNum>=1 and F_ProductKid={0};
                //select F_InventoryNum from T_ProductInventory where F_ProductKid= {0}";
                const string sql = @"DECLARE @F_InventoryNum int
select @F_InventoryNum = F_InventoryNum from T_ProductInventory where F_InventoryNum>=1 and F_ProductKid={0};
update T_ProductInventory set F_InventoryNum=F_InventoryNum-1 where F_InventoryNum>=1 and F_ProductKid={0};
select @F_InventoryNum";
                return await db.Sql(sql, productKid).ExecuteScalar<int>();
            }
        }

        public static async Task<int> RefundProduct(int productKid, DbTour db)
        {
            if (productKid <= 0) return -1;
            const string sql = @"update T_ProductInventory set F_InventoryNum=F_InventoryNum+1 where F_InventoryNum>=0 and F_ProductKid={0};";
            return await db.Sql(sql, productKid).ExecuteNonQuery();
        }
    }
}
